
// handle requests, request queues etc...
function ParaPara( url, load_info ) {

    // add mootools check here
    if(!load_info)
        alert("No para_load var? This won't work...");

    // methods /// ////////////////////////////////////////
    this.rpc_response = ParaPara_RPC_Response;
    this.rpc_failure  = ParaPara_RPC_Failure;
    this.send_rpc     = ParaPara_Send_RPC;

    this.start        = ParaPara_Start;
    this.stop         = ParaPara_Stop;
    this.init         = ParaPara_Init;

    this.uev_login     = ParaPara_UEV_Login;
    this.uev_logout    = ParaPara_UEV_Logout;

    this.sev_login        = ParaPara_SEV_Login;

    this.sev_para_info    = ParaPara_SEV_ParaInfo;
    this.sev_events       = ParaPara_SEV_Events;


    this.status_ok      = ParaPara_Status_OK;
    this.status_warn    = ParaPara_Status_Warn;
    this.status_error   = ParaPara_Status_Error;
    this.status_hide    = ParaPara_Status_Hide;

    this.format_time    = ParaPara_Format_Time;
    this.id_to_num      = ParaPara_ID_To_Num;


    // attributes /// 
    this.requester = new Para_Requester( url );
    this.status_console       = $('para_status_field');
    this.status_console_inner = $('para_status_field_inner');

    this.state     = new Para_State();
    this.forum     = null;
    if(load_info.forum)
        this.forum = new Para_Forum( );

    this.chat      = null;
    if(load_info.chat)
        this.chat = new Para_Chat( );

    this.linkroll  = null;
    if(load_info.linkroll)
        this.linkroll = new Para_LinkRoll( );

    // 
    this.poll_interval   = 10 * 1000;
    this.newest_event_id = 0;

    // Regexp to match MySQL datestamps
    this.timestamp_pattern = /^(\d{4})-(\d{2})-(\d{2})\s+(\d{2}):(\d{2}):(\d{2})$/;
    this.id_to_num_pattern = /(\d+)$/;
}


function ParaPara_Start() {
    this.init();
    this.chat.init();
}

function ParaPara_Stop() {
}

function ParaPara_Init() {
   // verify token, if there is one
    if( this.state.get_token() != null ) {
        var request = 
            {
                operation: "check_token",
                postback:  "check_token",
                param: {
                    token: this.state.get_token()
                }
            };
        //this.requester.send( request );
    }

    var request = {
        operation: "para_info",
        postback:  "para_info",
        param: {
        }
    };

    this.requester.send( request );
}


function ParaPara_RPC_Failure ( failure ) {
    alert("ParaPara_RPC_Failure called");
}


function ParaPara_RPC_Response( response ) {
    var postback = response.postback;

    // The RPC response dispatcher 

    if(response.token != null)
        this.state.set_token( response.token );

    if(postback.match(/^forum_/)) {
        this.forum.rpc_response( response );
        return;
    }
    else if(postback.match(/^chat_/)) {
        this.chat.rpc_response( response );
        return;
    }
    else if(postback.match(/^linkroll_/)) {
        this.linkroll.rpc_response( response );
        return;
    }


    

    switch (postback) {
    case "get_events":
        this.sev_events( response ); break;
    case "login":
        this.sev_login( response ); break;
    case "check_token":
        this.sev_login( response ); break;
    case "para_info":
        this.sev_para_info( response ); break;
    default:
        alert( "ParaPara has unknown postback:" + postback );
    }
}


function ParaPara_Send_RPC ( request ) {
    this.requester.send( request );
}


// User Events ////////////////////////////////////////

function ParaPara_UEV_Login() {

    var form = $('para_loginform');
    var username = form['uid'].get('value');
    var password = form['pwd'].get('value');

    var request = 
        {
            operation: "get_token",
            postback:  "login",
            param: {
                login: username,
                password: password
            }
        };
    this.requester.send( request );
    return false;
}


function ParaPara_UEV_Logout() {
     this.state.set_token( null );
     window.location = window.location;
}


// Server events //////////////////////////////////////
function ParaPara_SEV_Login( response ) {
    var status = response.status;
    if(status == "ok") {
        var token       = response.retval.token;
        var screen_name = response.retval.screen_name;
        var karma       = response.retval.karma;
        this.state.set_token( token );
        this.state.set_screen_name( screen_name );
        alert("log in now");
        window.location = window.location;
    }
    else {
        para_debug( "login failed postback=" + response.postback + 
                    " error=" + response.error_id +
                    " desc=" + response.description );
        if( response.postback == "login" )
            alert("FAIL! login failed...");
    }

}


function ParaPara_SEV_ParaInfo( response ) {
    var status = response.status;
    if(status == "ok") {
        var newest_event_id = response.retval.newest_event_id;
        if(newest_event_id == null)
            newest_event_id = 0;

        this.newest_event_id = newest_event_id;
        ParaPara_Fetch_Events.delay(this.poll_interval, this);        
    }
    else {
        alert("ParaPara_SEV_ParaInfo failed: " + response.error_id );
    }

}


// react to recent events
function ParaPara_SEV_Events( response ) {

    // Flags will be set in the for loop and actions will be taken
    var reload_chat       = false;
    var reload_threads    = false;

    var newest_event_id = response.retval.newest_id;

    if( newest_event_id == this.newest_event_id )
        return;


    var events = response.retval.events;

    para_debug("Got events:" + events.length );

    this.newest_event_id = newest_event_id;


    // send events to all modules that might be interested in them
    if(this.chat != null)
        this.chat.handle_events( events )

    if(this.forum != null)
        this.forum.handle_events( events )

}


function ParaPara_Fetch_Events() {

    var request = 
        {
            operation: "get_events",
            postback:  "get_events",
            param: {
                since_id: this.newest_event_id
            }
        };
    this.requester.send( request );

    ParaPara_Fetch_Events.delay(this.poll_interval, this);
}


// Status functions

function ParaPara_Status_OK( text ) {
    var console = this.status_console;
    var console_inner = this.status_console_inner;
    if(!(console && console_inner))
        return;

    console_inner.set('text', text);
    console_inner.set('class', 'para_status_field_ok');
    console.set('styles', {visibility: 'visible'});    
}


function ParaPara_Status_Warn( text ) {
    var console       = this.status_console;
    var console_inner = this.status_console_inner;
    if(!(console && console_inner))
        return;

    console.set('styles', {visibility: 'visible'});
    console_inner.set('class', 'para_status_field_warn');
    console_inner.set('text', text);
}


function ParaPara_Status_Error( text ) {
    var console       = this.status_console;
    var console_inner = this.status_console_inner;
    if(!(console && console_inner))
        return;

    console.set('styles', {visibility: 'visible'});
    console_inner.set('class', 'para_status_field_error');
    console_inner.set('text', text);
}


function ParaPara_Status_Hide( ) {
    var console       = this.status_console;
    console.set('styles', {visibility: 'hidden'});
}


// Util functions //////////////////////////////////////////////////

function ParaPara_Format_Time( datestamp ) {

    var res = datestamp.match( this.timestamp_pattern );

    if(res) {
        return res[4] + ":" + res[5] + ":" + res[6];
    }
    return null;
}


function ParaPara_ID_To_Num( id ) {
    var res = id.match( this.id_to_num_pattern );

    if(res) {
        return res[1];
    }
    return null;    
}
